#ifndef _UTILS_H
#define _UTILS_H

#include <pthread.h>
#include <stdarg.h>
#include <stdlib.h>

#include "list.h"

#define show_thread_msg(msg) \
    fprintf(stderr, "thread [%ld]: %s\n", pthread_self(), msg)

typedef void* (*thread_routinue_t)(void*);

// 私有结构
typedef struct {
    pthread_t tid;
    list_node_t node;
} thread_node_t;

static void run_threads(thread_routinue_t routine, ...) {
    va_list ap;
    va_start(ap, routine);
    thread_routinue_t p = routine;
    list_head_init(head);
    thread_node_t* ptn;

    while (p) {
        ptn = (thread_node_t*)malloc(sizeof(thread_node_t));
        list_append(&head, &ptn->node);
        pthread_create(&ptn->tid, NULL, p, NULL);
        p = va_arg(ap, thread_routinue_t);
    }
    va_end(ap);
    // 遍历链表，释放内存
    list_node_t *n, *nn;
    list_foreach_safe(n, nn, &head) {
        ptn = list_data(n, thread_node_t, node);
        pthread_join(ptn->tid, NULL);
        free(ptn);
    }
}

static void run_threads_with_args(thread_routinue_t routine, void* arg, ...) {
    va_list ap;
    va_start(ap, arg);
    thread_routinue_t p = routine;
    list_head_init(head);
    thread_node_t* ptn;

    while (p) {
        ptn = (thread_node_t*)malloc(sizeof(thread_node_t));
        list_append(&head, &ptn->node);
        pthread_create(&ptn->tid, NULL, p, arg);
        p = va_arg(ap, thread_routinue_t);
        arg = va_arg(ap, void*);
    }
    va_end(ap);
    // 遍历链表，释放内存
    list_node_t *n, *nn;
    list_foreach_safe(n, nn, &head) {
        ptn = list_data(n, thread_node_t, node);
        pthread_join(ptn->tid, NULL);
        free(ptn);
    }
}
#endif  // _UTILS_H